package edu.msse.signup.service;

import java.util.Collections;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceException;

import org.springframework.orm.jpa.JpaCallback;
import org.springframework.orm.jpa.support.JpaDaoSupport;

import edu.msse.signup.domain.Event;
import edu.msse.signup.domain.Position;
import edu.msse.signup.domain.TimeSlot;
import edu.msse.signup.domain.Users;

public class VolunteerServiceImpl extends JpaDaoSupport implements VolunteerService {
	
	public VolunteerServiceImpl() {
		super();
	}

	public void fillPositionTimeSlot(Position position, TimeSlot timeSlot,
			Users user) {
		
		if (timeSlot != null){
			TimeSlotService ts = new TimeSlotService();
			ts.addUser(timeSlot, user);
		}else {
			PositionService ps = new PositionService();
			ps.addUser(position, user);
		}
	}

    @SuppressWarnings("unchecked")
	public List getOpenPositionsAndTimeSlots(Event event) {
    	
    	return getJpaTemplate().find(
   			 "select p from Position p where p.event = ? and (" +
   			 "(p in (select t.position from TimeSlot t where size(t.users) < t.numberOfVolunteers))" +
   			 "or (size(p.timeSlots) = 0 and size(p.users) < p.numberOfVolunteers))", event);
    	
   }

      
    @SuppressWarnings("unchecked")
	public List getFilledPositionsAndTimeSlots(Event event){
		return getJpaTemplate().find(
                "select p, t from TimeSlot t, Position p, Event e where e = ? and (" +
                "(size(p.users) >= p.numberOfVolunteers and p in elements(e.positions)) or " +
                "(p = t.position and size(t.users) >= t.numberOfVolunteers and p in elements(e.positions)))", event);
		
	}

    public boolean unFillPosition(int userId, int positionId){
    	Users user = getJpaTemplate().find(Users.class, userId);
    	Position position = getJpaTemplate().find(Position.class, positionId);
    	
    	EntityManager em = getJpaTemplate().getEntityManagerFactory().createEntityManager();
    	EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            position=em.merge(position);
            user = em.merge(user);
            position.getUsers().remove(user);
            user.getPositions().remove(position);
            em.persist(position);
            em.persist(user);
            tx.commit();
            return true;
            
        } catch (Exception x) {
        	x.printStackTrace();
        	tx.rollback();
        	return false;
            
        }
    }
    
    public boolean unFillTimeSlot(int userId, long timeSlotId){
    	final Users user = getJpaTemplate().find(Users.class, userId);
    	final TimeSlot timeslot = getJpaTemplate().find(TimeSlot.class, timeSlotId);
    	
    	return (Boolean) getJpaTemplate().execute(new JpaCallback() {
    		
			public Object doInJpa(EntityManager em) throws PersistenceException {
				EntityTransaction tx = em.getTransaction();
		        try {
		        	tx.begin();
		            timeslot.getUsers().remove(user);
		            user.getTimeSlots().remove(timeslot);
		            TimeSlot mergeTimeSlot =em.merge(timeslot);
		            Users mergedUser = em.merge(user);
		            em.persist(mergeTimeSlot);
		            em.persist(mergedUser);
		            tx.commit();
		            return true;
		            
		        } catch (Exception x) {
		        	x.printStackTrace();
		        	tx.rollback();
		        	return false;
		            
		        }
			}});
    	
    	
    }
}
